package site.sorghum.ddl.proxy;

import lombok.extern.slf4j.Slf4j;
import site.sorghum.ddl.config.DdlGlobalConfig;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class ExeSqlProxy {

    private static final ReentrantLock fileLock = new ReentrantLock();

    public static ProxyRes exeSql(String sql, Object... args) {
        ProxyRes proxyRes = new ProxyRes();
        try {
            if (DdlGlobalConfig.banExe) {
                log.warn("[Sorghum-DDL] SQL execution is banned by configuration");
                proxyRes.setForceReturn(true);
            }

            // 构建完整SQL语句
            String fullSql = buildCompleteSql(sql, args).trim();

            // 记录SQL日志
            String logMessage = String.format(proxyRes.isForceReturn() ? "[Sorghum-DDL] No Executed SQL: %s" : "[Sorghum-DDL] Executed SQL: %s", fullSql);

            log.info(logMessage);

            if (DdlGlobalConfig.logPath != null && !DdlGlobalConfig.logPath.isEmpty()) {
                appendFile(fullSql, DdlGlobalConfig.logPath);
            }
            return proxyRes;
        } catch (Exception e) {
            log.error("[Sorghum-DDL] Error executing SQL proxy", e);
            return proxyRes.withForceReturn(true);
        }
    }

    /**
     * 将SQL日志追加到文件
     */
    public static void appendFile(String content, String logPath) {
        fileLock.lock();
        content = content.trim() + "\n";
        try {
            Path path = Paths.get(logPath);

            // 如果文件不存在，创建文件及其父目录
            if (!Files.exists(path)) {
                File file = path.toFile();
                File parent = file.getParentFile();
                if (parent != null && !parent.exists()) {
                    parent.mkdirs();
                }
                Files.createFile(path);
            }

            // 追加内容到文件
            Files.write(path,
                    content.getBytes(StandardCharsets.UTF_8),
                    StandardOpenOption.APPEND);
        } catch (IOException e) {
            log.error("Failed to write SQL log to file: " + logPath, e);
        } finally {
            fileLock.unlock();
        }
    }

    /**
     * 将参数拼接到SQL语句中，生成完整SQL
     */
    private static String buildCompleteSql(String sql, Object... args) {
        if (args == null || args.length == 0) {
            return sql;
        }

        StringBuilder fullSql = new StringBuilder(sql);
        fullSql.append(" -- Parameters: ");

        for (int i = 0; i < args.length; i++) {
            fullSql.append(args[i] != null ? args[i].toString() : "null");
            if (i < args.length - 1) {
                fullSql.append(", ");
            }
        }

        return fullSql.toString();
    }
}